﻿using Bandit.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ETC.DLEDLightingSystemPlus.Helpers
{
    public class DLEDLightingHelper : DeviceBase
    {
        public delegate void OnReceivedHandler(object sender, string data);

        public event OnReceivedHandler OnReceived;



        //#region 实例
        //private static DLEDLightingHelper _Instance;
        ///// <summary>
        ///// 实例
        ///// </summary>
        //public static DLEDLightingHelper Instance
        //{
        //    get
        //    {
        //        if (_Instance == null)
        //        {
        //            _Instance = new DLEDLightingHelper(ConfigHelper.GetVauleToString("TestPortName"));
        //        }
        //        return _Instance;
        //    }
        //    set
        //    {
        //        _Instance = value;
        //    }
        //}
        //#endregion

        public void Reset()
        {
            //if (_Instance != null)
            //{
            //    _Instance.IsAutoReopen = false;
            //    _Instance.BanditSerialPort.Close();
            //    _Instance.BanditSerialPort = null;
            //    _Instance = null;
            //}
            this.BanditSerialPort.Close(); 
            this.BanditSerialPort.Open();

        }

        public void Close()
        {
            if (this.BanditSerialPort != null)
            {
                this.BanditSerialPort.Close();
                this.BanditSerialPort = null;
            }
        }

        public DLEDLightingHelper(string portName) : base(portName)
        {




        }

        protected override void BanditSerialPort_OnReceived(object sender, OnReceivedArgs e)
        {
            //_ResponseData = e.NormalData + this.BanditSerialPort.EndFlag;
            if (e.NormalData.Contains("^"))
            {
                LogHelper.Info(e.NormalData);
                LogHelper.Info("收到FW发来的心跳包");

                //_ResponseData.Replace("^", "");

                this.SetRS232Connect();
               
            }
            if (e.NormalData.Contains("$"))
            {
                LogHelper.Info(e.NormalData);
                LogHelper.Info("收到FW复位信息");

                OnReceived(this, "FWReset");
                _ResponseData = string.Empty;
                this.Set();
                return;
            }

            if (!e.NormalData.Contains("}"))
            {
                _ResponseData += e.NormalData;
                return;
            }

            _ResponseData += e.NormalData;

            if (_ResponseData.Contains("^"))
            {
                _ResponseData = _ResponseData.Replace("^", "");

                this.SetRS232Connect();
            }

            LogHelper.Info(string.Format("[{0}]SeriaPort Recv -> {1}", base.PortName, _ResponseData));
             
            if (_SendCmd == "PowerOff")
            {
                //_ResponseData.Replace("\"ERROR\": \"DUT is not connected\",", "");
                _ResponseData = _ResponseData.Substring(_ResponseData.IndexOf('{')); 
                
                LogHelper.Info(string.Format("PowerOff接收处理[{0}]SeriaPort Recv -> {1}", base.PortName, _ResponseData));

            }

            if (_ResponseData.Contains("DUTOUT")|| _ResponseData.Contains("DUT is not connected") || _ResponseData.Contains("ERROR:INT Wrong"))
            {
                OnReceived(this, "Stop");
            }

            base.Set();

        }

        private string _SendCmd = string.Empty;

        public override void Send(string cmd, bool isThread = false, int delayMS = 200)
        {
            //this.BanditSerialPort.EndFlag = "}";
            //this._ResponseState = false;

            //AddByBandit 2024年4月25日 14:20:48
            this._AutoResetEvent.Reset();

            this._ResponseData = string.Empty;

            _SendCmd = string.Empty;
            this._SendCmd = cmd;

            LogHelper.Info(string.Format("[{0}]SeriaPort Send -> {1}", base.PortName, cmd));

            if (isThread)
            {
                Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(delayMS);

                    this.BanditSerialPort.Send(cmd, DataTypeBySerialPort.Text, true);

                }).LogExceptions("Send - " + cmd);
            }
            else
            {
                this.BanditSerialPort.Send(cmd, DataTypeBySerialPort.Text, true);


            }
        }

        private bool SendCmd(string cmd, double waitTimeSecond, bool isCheckSuccessFlag = true)
        {
            bool result = false;

            for (int i = 0; i < 3; i++)
            {
                this.Send(cmd);

                result = this.Wait(waitTimeSecond);

                if (result)
                {
                    if (isCheckSuccessFlag)
                    {
                        if (!string.IsNullOrWhiteSpace(_ResponseData) && _ResponseData.ToLower().Contains("success"))
                        {
                            break;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                if (i != 2)
                {
                    Thread.Sleep(50); //等50毫秒重新尝试

                    Bandit.Helpers.LogHelper.Info(string.Format("[Err][{0}] Send Cmd({1}) Fail, Try Resend...{2}", base.PortName, cmd, i));
                }
            }

            return result;
        }

        #region 指令集

        /// <summary>
        /// HELP 信息指令:"HELP"
        /// </summary>
        /// <returns></returns>
        public string GetHelpInfoCommand()
        {
            string Cmd = "HELP";

            this.SendCmd(Cmd, 10);

            //this.Send(Cmd);

            //this.Wait(10);

            return _ResponseData;
        }

        /// <summary>
        /// MCU版本指令:"INFO"
        /// </summary>
        /// <returns></returns>
        public string GetMCUVersionsComnand()
        {
            string Cmd = "INFO";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        /// <summary>
        /// 获取热敏电阻数据指令：getNtcData
        /// </summary>
        /// <returns>
        /// { 	"CMD" : "getNtcData" ,  		
        ///     "NTC resistance R"  : "4051.458008" , 
		///     "NTC temperature C" : "51.319927" ,  	
        ///     "result" : "success"  
        /// }
        /// </returns>
        public string GetNTCDataCommand()
        {
            string Cmd = "getNtcData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        /// <summary>
        ///  选择电流测试范围，0测量范围0~8A,1测量范围0-800mA
        /// </summary>
        /// <param name="Range"></param>
        /// <returns></returns>
        public string SwichLEDPowerAdcRange(int Range)
        {
            string Cmd = "swichLEDPowerAdcRange " + Range.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        /// <summary>
        /// 指令让硬件进行自检，若是异常不会对产品进行上电，此时软件提示测试设备异常，停止测试
        /// </summary>
        /// <returns></returns>
        public string SelfCheckResult()
        {
            string Cmd = "SelfCheck";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }



        ///// <summary>
        ///// 测量IC背光使能时候总电流
        ///// </summary>
        ///// <returns></returns>
        //public string TestLEDCurrent()
        //{
        //    string Cmd = "testLEDCurrent 0";

        //    this.SendCmd(Cmd, 10);

        //    return _ResponseData;
        //}

        /// <summary>
        /// 测试IC通讯是否正常，返回数据还没确定
        /// </summary>
        /// <returns></returns>
        public string TestDriverIC()
        {
            string Cmd = "testDriverIC ";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        /// <summary>
        /// 获取LED open信息，返回11个IC的16个通道OPEN数据，每一个位代表一个通道，0表示正常，1表示OPEN
        /// </summary>
        /// <returns></returns>
        public string GetLEDOpenTestData()
        {
            string Cmd = "getLEDOpenTestData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        /// <summary>
        /// 获取LED short信息，返回11个IC的16个通道SHORT数据，每一个位代表一个通道，0表示正常，1表示SHORT
        /// </summary>
        /// <returns></returns>
        public string GetLEDShortTestData()
        {
            string Cmd = "getLEDShortTestData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }


        /// <summary>
        /// 获取LED 电压/电流（VBL）信息
        /// </summary>
        /// <returns></returns>
        public string GetLEDVolCurData()
        {
            string Cmd = "getLEDVolCurData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string GetTestData()
        {
            _ResponseData = string.Empty;

            string Cmd = "GET ADC VOLTAGE";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        #endregion

        #region SetRS232ConStart

        public bool SetRS232ConStart()
        {
            string Cmd = "setRS232ConStart";

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion
        #region SetRS232ConStart

        public void SetRS232Connect()
        {
            string Cmd = "setRS232Connect";

            LogHelper.Info(string.Format("[{0}](Thread)SeriaPort Send -> {1}", base.PortName, Cmd));

            //this.Send(Cmd, false);
            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(100);

                this.BanditSerialPort.Send(Cmd, DataTypeBySerialPort.Text, true);

            }).LogExceptions("Send - " + Cmd);

        }
        #endregion

        #region 配置指令

        #region CaseCode设置
        public bool SetCaseCode(int CaseCode)
        {
            string Cmd = "setCaseCode " + CaseCode.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }

        #endregion

        #region VLED 设置
        public bool SetVBL(double VblValue)
        {
            string Cmd = "setVBL " + VblValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }

        #endregion

        #region PWM Mode 设置
        public bool SetPWMMode(int pwmMode)
        {
            string Cmd = "setPwmMode " + pwmMode.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }

        #endregion

        #region 过压过流设置
        public bool SetOCPOVP(double VLEDOVPValue, double VLEDUVPValue, double VLEDOCPValue, double ICOVPValue, double ICUVPValue, double ICOCPValue)
        {
            string Cmd = "setOCPOVP " + VLEDOVPValue.ToString() + " " + VLEDUVPValue.ToString() + " " + VLEDOCPValue.ToString() + " " + ICOVPValue.ToString() + " " + ICUVPValue.ToString() + " " + ICOCPValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }

        public bool SetOCPOVP(double VLEDCVPValue, double VLEDOCPValue, double ICOVPValue, double ICOCPValue)
        {

            string Cmd = "setOCPOVP " + VLEDCVPValue.ToString() + " " + VLEDOCPValue.ToString() + " " + ICOVPValue.ToString() + " " + ICOCPValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);

        }
        #endregion

        #region MC值设置
        public bool SetMC(double MCValue)
        {
            string Cmd = "setMC " + MCValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region DC值设置
        public bool SetDC(double DCValue)
        {
            string Cmd = "setDC " + DCValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region BC值设置
        public bool SetBC(double BCValue)
        {
            string Cmd = "setBC " + BCValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region Scale值设置
        public bool SetSCALE(double ScaleValue)
        {
            string Cmd = "setSCALE " + ScaleValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region ILED值设置
        public bool SetILED(int ILEDValue)
        {
            string Cmd = "setILED " + ILEDValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region SRC值设置
        public bool SetSRC(double SrcValue)
        {
            string Cmd = "setSRC " + SrcValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region LEDNUM值设置
        public bool SetLEDNUM(double LedNumValue)
        {
            string Cmd = "setLEDNUM " + LedNumValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region RSET值设置
        public bool SetRSET(double RSETValue)
        {
            string Cmd = "setRSET " + RSETValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion

        #region LEDNUM值设置
        public bool SetCLK(double CLKValue)
        {
            string Cmd = "setCLK " + CLKValue.ToString();

            return this.SendCmd(Cmd, App.CmdTimeOut, true);
        }
        #endregion
        #endregion

        #region 测试指令

        #region Pin短路开路测试
        public string GetPinOSTestData()
        {
            string Cmd = "getPinOSTestData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;

        }
        #endregion

        #region NTC极性测试
        public string GetDiodePolarity()
        {
            string Cmd = "getDiodePolarity";

            this.SendCmd(Cmd, 10);

            return _ResponseData;

        }
        #endregion

        #region 常温下热敏电阻测试 、点灯下的热敏电阻
        public string GetNTCData()
        {
            string Cmd = "getNtcData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        #endregion

        #region 芯片待机电流 -- 芯片正常运行电流 
        /// <summary>
        /// 获取pVDD电压,也就是驱动IC电压电流
        /// </summary>
        /// <returns></returns>
        public string GetLEDDriverICStandbyVolCurData()
        {
            string Cmd = "getLEDDriverICStandbyVolCurData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string GetLEDDriverICWorkingVolCurData()
        {
            string Cmd = "getLEDDriverICWorkingVolCurData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        #endregion

        #region IFB
        public string GetIFBData()
        {
            string Cmd = "getIFBData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        #endregion

        #region VLED亮度全关的漏电流 0  、全画面高电流、全画面低电流
        /// <summary>
        /// 全部LED高低电流点灯测试
        /// </summary>
        /// <returns></returns>
        public string GetAllLEDTestData(double CurrentValue)
        {
            string Cmd = "getAllLEDTestData " + CurrentValue.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        #endregion

        #region 单路LED电流  高、低
        /// <summary>
        /// 单个LED逐一进行电压电流测试，返回176个LED电压电流数据
        /// </summary>
        /// <returns></returns>
        public string GetSingleLEDTestData(double currentValue)
        {
            string Cmd = "getSingleLEDTestData " + currentValue.ToString() + " 0";

            this.SendCmd(Cmd, 1000);

            return _ResponseData;
        }

        #endregion

        #region LED单芯片回路低电流\高电流
        public string GetICLEDTestData(double CurrentValue)
        {
            string Cmd = "getICLEDTestData " + CurrentValue.ToString() + " 0";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        #endregion

        #region AUO显示
        public string ShowAUO(double ForegroundLightValue, double BackgroundLightValue)
        {
            string Cmd = "showAUO " + ForegroundLightValue.ToString() + " " + BackgroundLightValue.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }
        #endregion

        public string ShowSingleLEDLocation(string ForegroundLightValue, string BackgroundLightValue, string IC, string ChannelNum)
        {

            string Cmd = "ShowSingleLEDLocation " + ForegroundLightValue.ToString() + " " + BackgroundLightValue.ToString() + " " + IC.ToString() + " " + ChannelNum.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;

        }

        public string ShowICLEDLocation(string ForegroundLightValue, string BackgroundLightValue, string IC)
        {

            string Cmd = "ShowICLEDLocation " + ForegroundLightValue.ToString() + " " + BackgroundLightValue.ToString() + " " + IC.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;

        }

        public string SetDIYPictureData(string ICNum, string Data)
        {
            string Cmd = "setDIYPictureData " + ICNum.ToString() + Data.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string SetDIYPictureData(string ICNum, string ScanNum, string Data)
        {
            string Cmd = "setDIYPictureData " + ICNum.ToString() + " " + ScanNum.ToString() + Data.ToString();

            this.SendCmd(Cmd, 10);

            //this.Wait(10);

            return _ResponseData;
        }

        public string showDIYPicture(int Value)
        {
            string Cmd = "showDIYPicture " + Value.ToString(); ;

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string SetCheckerBoardPictureData(string ICNum, string Data)
        {
            string Cmd = "setCheckerBoardPictureData " + ICNum.ToString() + Data.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string ShowCheckerBoardPicture(int value)
        {
            string Cmd = "showCheckerBoardPicture " + value.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        public string GetESDTestData(int ODDEVENValue)
        {
            string Cmd = "getESDTestData " + ODDEVENValue.ToString();

            this.SendCmd(Cmd, 10);

            return _ResponseData;

        }

        #region 10uA电流测试
        public string GetUATestData()
        {
            string Cmd = "getUATestData";

            this.SendCmd(Cmd, 10);

            return _ResponseData;
        }

        #endregion

        #region PowerOFF
        /// <summary>
        /// 关闭电源，测试完成后使用该指令
        /// </summary>
        /// <returns></returns>
        public string PowerOff()
        {
            string Cmd = "PowerOff";

            this.SendCmd(Cmd, 5);

            return _ResponseData;
        }
        #endregion

        #region GetTestResult
        /// <summary>
        /// 测试完成后将结果发给点灯机 - AddByBandit 2024年8月27日 14:56:35
        /// </summary>
        /// <returns></returns>
        public string GetTestResult(bool result)
        {
            string cmd = string.Format("getTestResult {0}", result ? 1 : 0);

            this.SendCmd(cmd, 3);

            return _ResponseData;
        }
        #endregion

        #region DIYStart
        /// <summary>
        /// [TX037] 全电流测试结束后要测试DIY Pattern前执行 - AddByBandit 2024年8月27日 16:59:35
        /// </summary>
        /// <returns></returns>
        public string DIYStart()
        {
            string cmd = string.Format("DIYStart");

            this.SendCmd(cmd, 3);

            return _ResponseData;
        }
        #endregion

        #region DIYEnd
        /// <summary>
        /// [TX037] DIY Pattern测试结束后执行 - AddByBandit 2024年8月27日 16:59:35
        /// </summary>
        /// <returns></returns>
        public string DIYEnd()
        {
            string cmd = string.Format("DIYEnd");

            this.SendCmd(cmd, 3);

            return _ResponseData;
        }
        #endregion

        #endregion


    }
}
